using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using System.Drawing;
using System.Web.Caching;
using System.Configuration;
using System.Drawing.Imaging;

using Adge.Common;




namespace Adge.Web.UI.Providers
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://www.adge.edu.cn/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class ThumbJpeg : IHttpHandler
    {
        int _width, _height;
        String _path;
        bool _bStretch, _bBevel;
        Thumbnail thumb;

        public void ProcessRequest(HttpContext context)
        {
            Image image;
            String sCacheKey;
            bool bFoundInCache = true; // by default
            // create our COM thumbnail generator
            thumb = new Thumbnail();
            // get width and height
            if (context.Request["Width"] != null)
                _width = Int32.Parse(context.Request["Width"]);
            else
            {
                try { _width = int.Parse(System.Configuration.ConfigurationManager.AppSettings["DefaultWidth"]); }
                catch (Exception ex)
                {
                    while (ex != null)
                    {
                        LogMessage(ex.Message);
                        ex = ex.InnerException;
                    } _width = 150;
                }
            }
            if (context.Request["Height"] != null)
                _height = Int32.Parse(context.Request["Height"]);
            else
            {
                try
                {
                    _height = int.Parse(ConfigurationManager.AppSettings["DefaultHeight"]);
                }
                catch (Exception ex)
                {
                    while (ex != null)
                    {
                        LogMessage(ex.Message);
                        ex = ex.InnerException;
                    }
                    _height = 150;
                }
            }
            // get path of 'no thumbnail' image
            const String NoThumbFile = "NoThumb.gif"; //"victory.jpg";
            String sNoThumbPath = context.Request.MapPath(
             context.Request.ApplicationPath.TrimEnd('/') + "/" + NoThumbFile);
            // map requested path
            if (context.Request["oFilePath"] != null)
                _path = context.Request.MapPath(context.Request["oFilePath"]);
            else _path = sNoThumbPath;
            //_path = context.Request.MapPath("/images/OLIMP011.jpg"); //-->for test
            // allow stretch of thumbnails
            _bStretch = (context.Request["AllowStretch"] == "true");
            // bevel thumbnails
            _bBevel = (context.Request["Bevel"] == "true");
            // put parameters for thumbnail requested
            thumb.SetParams(_path, _width, _height, _bStretch, _bBevel);
            // get a reference to the cache object
            Cache MyCache = context.Cache;
            sCacheKey = thumb.GetUniqueThumbName();
            // --- remove from cache when we want to refresh
            bool bRefresh = (context.Request["Refresh"] == "true");
            if (bRefresh)
                MyCache.Remove(sCacheKey);
            if (MyCache[sCacheKey] == null)
            { // the thumbnail does not exist in cache, create it...
                // Create a bitmap of the thumbnail and show it
                try
                {
                    image = thumb.ExtractThumbnail();
                    bFoundInCache = false;
                }
                catch (Exception e)
                {
                    while (e != null)
                    {
                        LogMessage(e.Message);
                        e = e.InnerException;
                    }
                    // requested image cannot be loaded, try to load the 'NoThumb' image
                    _path = sNoThumbPath;
                    thumb.SetParams(_path, _width, _height, _bStretch, false);
                    sCacheKey = thumb.GetUniqueThumbName();
                    if (MyCache[sCacheKey] == null)
                    {
                        try
                        {
                            image = thumb.ExtractThumbnail();
                            bFoundInCache = false;
                        }
                        catch (Exception e2)
                        {
                            while (e2 != null)
                            {
                                LogMessage(e2.Message);
                                e2 = e2.InnerException;
                            }
                            return;
                        }
                    }
                    else
                    {
                        image = (Bitmap)MyCache[sCacheKey];
                    }
                } // end catch 
            }
            else
            { // bitmap is in cache
                image = (Bitmap)MyCache[sCacheKey];
            }
            context.Response.ContentType = "image/Jpeg";
            Thumbnail.SaveImage(image, context.Response.OutputStream, Thumbnail.GetImageCodecInfo(ImageFormat.Jpeg));
            //bitmap.Save(context.Response.OutputStream, ImageFormat.Jpeg);
            //if(bFoundInCache) LogMessage("Found in cache");
            // else LogMessage("NOT Found in cache");
            //cache thumbnail, make it dependent upon the file and thumbnail size
            bool bUseCache = !(ConfigurationManager.AppSettings["UseCache"] == "false");
            if (!bFoundInCache && bUseCache)
            {
                CacheDependency dependency = new CacheDependency(_path);
                int mins; try
                {
                    mins = int.Parse(ConfigurationManager.AppSettings["SlidingExpireMinutes"]);
                }
                catch (Exception ex)
                {
                    while (ex != null)
                    {
                        LogMessage(ex.Message);
                        ex = ex.InnerException;
                    }
                    mins = 20;
                }
                MyCache.Insert(sCacheKey, image, dependency,
                   Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(mins),
                   CacheItemPriority.Default, new CacheItemRemovedCallback(RemovedCallback));
                dependency.Dispose();
            }
            // bitmap in cache, dont dispose yet
            //bitmap.Dispose ();
        }

        static public void RemovedCallback(String k, Object item, CacheItemRemovedReason r)
        {
            ((Bitmap)item).Dispose();
            //LogMessage("Callback");
        }

        // for custom tracing, normal tracing does not work with WebHandlers
        static void LogMessage(String mess)
        {
            StreamWriter sw = new StreamWriter(HttpContext.Current.Server.MapPath("logs\\ASP.NET_log.txt"), true);
            sw.WriteLine(mess);
            sw.Close();
        }

        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
    }
}
